import datetime

from ctaBase import *
from ctaTemplate import *
from indicators import Indicators
from utils import MinKLineGenerator

class My_RSI(CtaTemplate):
    """RSI指标策略v3版本--多周期-旧方法实现
    """
    def __init__(self):
        super().__init__()

        # 参数映射表
        self.paramMap = {
            'period': 'K线周期',
            'tradetype': '交易类型',
            'order_volume': '下单手数',
            # 'istime': '是否选择时间段',
            # 'startdt': '开始时间',
            # 'enddt': '结束时间',
            # 'istlimit': '是否限制次数',
            # 'tlimit': '次数限制',
            'exchange': '交易所',
            'vtSymbol': '合约代码',
        }

        # 变量映射表
        self.varMap = {
            'trading': '交易中',
            # 'excTimes': '执行次数',
            'pos': '持仓',
        }
        
        # RSI参数及区间
        self.R = 6
        # self.S = 12
        # self.I = 24
        self.rup = 80
        self.rdm = 20

        # 定义两种逻辑  B 买 S 卖
        self.tradetypes = ['B','S'] 

        # 定义两种对手价报单价格优先方式
        self.pricetypes = ['D1', 'D2']

        self.period = 1
        self.tradetype = 'B'
        self.pricetype = 'D1'
  
        # self.istime = False
        # self.startdt = '09:00:00'
        # self.enddt = '15:00:00'

        # self.istlimit = False
        # self.tlimit = 10
        # # 填写的时候一定要加''，来确保该字段为string,如'119016'
        # self.investor = ''


        # self.widgetClass = KLWidget
        # self.widget: KLWidget = None
        # self.indicators: Indicators = None
        # self.kline_generator: MinKLineGenerator = None

         # 策略参数
        self.exchange = ""
        self.vtSymbol = ""
        self.order_volume = 1  # 下单手数
        # self.kline_style = "M1" # K 线类型, 具体看 core.pyi 中的 KLineStyle 定义
 

        self.current_rsi = 0  # 当前 K 线rsi数值
        self.prev_rsi = 0  # 上一根 K 线rsi数值
        self.c5_current_rsi = 0  # 当前 K 线5分钟 rsi数值
        self.c5_prev_rsi = 0  # 上一根 K 线5分钟 rsi数值


        self.trading = False

    def onStart(self):
        """启动策略（必须由用户继承实现）"""
        # 获取1分钟k线数据
        self.bm = BarManager(self.onBar, 1)
        # 获取5分钟k线数据
        self.bm5 = BarManager(self.onBar, 5,onXminBar=self.onXminBar)

        self.am = ArrayManager()
        self.am5 = ArrayManager()
        self.loadBar(3,func=self.onBar)


        # self.output('1分钟k线收盘价',self.am.close)
        # self.output('5分钟k线收盘价',self.am5.close)
        super().onStart()

    def onBar(self, bar):
        """收到Bar推送"""

        self.output('onBar',bar.__dict__)
        # 记录数据
        self.bm5.updateBar(bar)
        self.am.updateBar(bar)      
        
        # 计算指标
        self.calc_indicator(bar)

        # 计算信号
        self.calc_signal(bar)

        # 信号执行
        # self.execSignal(self.volume)


        if self.tradeDate != bar.date:
            self.tradeDate = bar.date



    def onXminBar(self, bar):
        self.output('onXminBar',bar.__dict__)
        if not self.am5.updateBar(bar):
            return
  
    # def onTick(self, tick):
    #     """收到行情TICK推送"""
    #     super().onTick(tick)

    #     # 过滤涨跌停和集合竟价
    #     if tick.lastPrice == 0 or tick.askPrice1 == 0 or tick.bidPrice1 == 0:
    #         return
    #     self.tick = tick
    #     self.askPrice1 = tick.askPrice1  # 卖盘价1
    #     self.bidPrice1 = tick.bidPrice1  # 买盘价1
    #     self.bm.updateTick(tick)

    def calc_indicator(self,bar) -> None:
        """计算指标数据"""
        currentArr = self.am.rsi(self.R,array=True)
        # self.output('M1当前rsi6参数值:', currentArr)
        # self.output('M1当前rsi6参数值:', currentArr[-1],'上一个rsi6参数值:', currentArr[-2])
        self.current_rsi,self.prev_rsi = round(currentArr[-1], 2),round(currentArr[-2],2) # 对指标的数值进行四舍五入
        """计算5分钟指标数据"""
        c5_Arr = self.am5.rsi(self.R,array=True)
        # self.output('M5当前rsi6参数值:', c5_Arr)
        # self.output('M5当前rsi6参数值:', c5_Arr[-1],'上一个rsi6参数值:', c5_Arr[-2])
        self.c5_current_rsi,self.c5_prev_rsi = round(c5_Arr[-1], 2),round(c5_Arr[-2],2) # 对指标的数值进行四舍五入


    def calc_signal(self, bar) -> None:
        """计算交易信号"""

        # 判断是否要进行交易
        self.buy_signal = (self.current_rsi > self.rdm) & (self.prev_rsi <= self.rdm)
        self.short_signal = (self.c5_current_rsi < self.rup) & (self.c5_prev_rsi >= self.rup)
        # 交易价格
        self.long_price = bar.close  #做多操作时的买入价格
        self.short_price = bar.close #做空操作时的卖出价格
        if self.buy_signal or self.short_signal: 
            # 5分钟卖出信号会每钟打印一次  这个问题需要处理掉 5分钟卖出信号只使用一次
            self.output('RSI交易信号：',
                        'buy:',self.buy_signal,
                        'short:',self.short_signal,
                        'M1的rsi值:',self.current_rsi,
                        'M1上一分钟的值:',self.prev_rsi,
                        'M5的rsi值:',self.c5_current_rsi,
                        'M5上一分钟的值:',self.c5_prev_rsi,
                        '当前价格:',bar.close,
                        '交易时间',bar.datetime)


    def onStop(self):
        """停止策略（必须由用户继承实现）"""
        # 订单和成本管理
        super().onStop()